<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="h5b6B" id="h5b6B"><span data-lake-id="u098a1437" id="u098a1437">典型回答</span></h1>
  <p data-lake-id="u9817f96e" id="u9817f96e"><span data-lake-id="u660d5a43" id="u660d5a43">我们知道，在foreach的同时修改集合，会触发fail-fast机制，要避免fail-fast机制，有如下处理方案：</span></p>
  <ol list="uc228e9fb">
   <li fid="u610a3e18" data-lake-id="u30f33768" id="u30f33768"><span data-lake-id="udba0e64f" id="udba0e64f">通过普通的for循环</span></li>
  </ol>
  <pre lang="java"><code>
public void listRemove() { 
    List&lt;Student&gt; students = this.getStudents(); 
    for (int i=0; i&lt;students.size(); i++) { 
        if (students.get(i).getId()%3 == 0) { 
            Student student = students.get(i); 
            students.remove(student); 
            //做一次i--，避免漏删
            i--;
        } 
    } 
} 
</code></pre>
  <ol list="uc228e9fb" start="2">
   <li fid="u610a3e18" data-lake-id="u2b54ca3a" id="u2b54ca3a"><span data-lake-id="u8a29c261" id="u8a29c261">使用迭代器循环</span></li>
  </ol>
  <pre lang="java"><code>
public void iteratorRemove() { 
    List&lt;Student&gt; students = this.getStudents(); 
    Iterator&lt;Student&gt; stuIter = students.iterator(); 
    while (stuIter.hasNext()) { 
        Student student = stuIter.next(); 
        if (student.getId() % 2 == 0) {
            //这里要使用Iterator的remove方法移除当前对象，如果使用List的remove方法，则同样会出现ConcurrentModificationException 
        	stuIter.remove();
        } 
    }
} 
</code></pre>
  <ol list="uc228e9fb" start="3">
   <li fid="u610a3e18" data-lake-id="ub9fac558" id="ub9fac558"><span data-lake-id="udfdbbf4b" id="udfdbbf4b">将原来的copy一份副本，遍历原来的list，然后删除副本（fail-safe）</span></li>
  </ol>
  <pre lang="java"><code>
public void copyRemove() {
    // 注意，这种方法的equals需要重写
	List&lt;Student&gt; students = this.getStudents();
    List&lt;Student&gt; studentsCopy = deepclone(students);
    for(Student stu : students) {
        if(needDel(stu)) {
            studentsCopy.remove(stu);
        }
    }
}
</code></pre>
  <ol list="ub6a11d5d" start="4">
   <li fid="u96b3bdad" data-lake-id="uaa21d323" id="uaa21d323"><span data-lake-id="u23100fa6" id="u23100fa6">使用并发安全的集合类</span></li>
  </ol>
  <pre lang="java"><code>
public void cowRemove() { 
    List&lt;String&gt; students = new CopyOnWriteArrayList&lt;&gt;(this.getStudents());
    for(Student stu : students) {
        if(needDel(stu)) {
            students.remove(stu);
        }
    }
}
</code></pre>
  <ol list="u801f4756" start="5">
   <li fid="u4e8915bd" data-lake-id="uef8a30e0" id="uef8a30e0"><span data-lake-id="u63ac19d9" id="u63ac19d9">通过Stream的过滤方法，因为Stream每次处理后都会生成一个新的Stream，不存在并发问题，所以Stream的filter也可以修改list集合</span></li>
  </ol>
  <p data-lake-id="u18f99ea5" id="u18f99ea5"><span data-lake-id="ube1a7fb9" id="ube1a7fb9">​</span><br></p>
  <pre lang="java"><code>
public List&lt;String&gt; streamRemove() { 
    List&lt;String&gt; students = this.getStudents();
    return students.stream()
        .filter(this::notNeedDel)
        .collect(Collectors.toList());
}

</code></pre>
  <p data-lake-id="u7923aa15" id="u7923aa15"><span data-lake-id="ufe9d7346" id="ufe9d7346">​</span><br></p>
  <ol list="u801f4756" start="6">
   <li fid="u4e8915bd" data-lake-id="u0cd4744a" id="u0cd4744a"><span data-lake-id="ud6a27b8f" id="ud6a27b8f">通过removeIf方法，实现元素的过滤删除。removeIf() 方法用于删除所有满足特定条件的数组元素</span></li>
  </ol>
  <p data-lake-id="ued69dc3c" id="ued69dc3c"><br></p>
  <pre lang="java"><code>
arraylist.removeIf(this::needDel);
</code></pre>
 </body>
</html>